package com.xbongbong.workorder.service.impl;

import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.model.PaasEsModel;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.pojo.dto.FormDataDeleteBatchDTO;
import com.xbongbong.paas.pojo.vo.FormDataDeleteBatchVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.parent.pojo.delete.ErrorDataPojo;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.WorkOrderErrorCodeEnum;
import com.xbongbong.pro.message.constant.WorkOrderPushConstant;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.help.PushHelper;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.outstock.pojo.dto.OutStockListDTO;
import com.xbongbong.pro.rabbitmq.producer.BaseProducer;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.WorkOrderEntity;
import com.xbongbong.saas.domain.entity.ext.WorkOrderFormEntityExt;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.OutstockTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.model.OutstockModel;
import com.xbongbong.saas.model.WorkOrderFlowNodeModel;
import com.xbongbong.saas.model.WorkOrderFlowUserModel;
import com.xbongbong.saas.model.WorkOrderFormModel;
import com.xbongbong.saas.model.WorkOrderModel;
import com.xbongbong.saas.model.WorkOrderProductModel;
import com.xbongbong.workorder.abstracts.AbstractWorkOrderDeleteService;
import com.xbongbong.workorder.service.WordOrderDeleteService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2022/02/09 11:26
 */
@Service("workOrderDeleteServiceImpl")
public class WorkOrderDeleteServiceImpl extends AbstractWorkOrderDeleteService implements WordOrderDeleteService {

    @Resource
    private WorkOrderFormModel workOrderFormModel;
    @Resource
    private OutstockModel outstockModel;
    @Resource
    private WorkOrderModel workOrderModel;
    @Resource
    private PushHelper pushHelper;
    @Resource
    private PaasEsModel paasEsModel;
    @Resource
    private WorkOrderProductModel workOrderProductModel;
    @Resource
    private WorkOrderFlowNodeModel workOrderFlowNodeModel;
    @Resource
    private WorkOrderFlowUserModel workOrderFlowUserModel;
    @Resource
    private BaseProducer baseProducer;
    @Resource
    private MongoLogHelp mongoLogHelp;

    @Override
    public List<Integer> businessType() {
        return Arrays.asList(XbbRefTypeEnum.WORK_ORDER.getCode());
    }

    @Override
    public FormDataDeleteBatchVO deleteWorkflow(FormDataDeleteBatchDTO formDataDeleteBatchDTO) throws XbbException {
        List<Long> contactIdIn = formDataDeleteBatchDTO.getDataIdList();
        String corpid = formDataDeleteBatchDTO.getCorpid();
        workOrderModel.deleteBatch(contactIdIn, corpid);
        workOrderProductModel.deleteByWorkOrderIdIn(contactIdIn, corpid);

        return new FormDataDeleteBatchVO();
    }

    @Override
    public WorkOrderFormEntityExt getForm(FormDataDeleteBatchDTO formDataDeleteBatchDTO) throws XbbException {
        Long formId = formDataDeleteBatchDTO.getFormId();
        String corpid = formDataDeleteBatchDTO.getCorpid();
        if (Objects.equals(formId, 0L)) {
            // 如果该工单有已生成工单出库单时，不允许删除(批量时只要有一个有问题就返回错误)
            OutStockListDTO outstockListDTO = new OutStockListDTO();
            BeanUtil.copyProperties(formDataDeleteBatchDTO, outstockListDTO);
            outstockListDTO.setRefIdIn(formDataDeleteBatchDTO.getDataIdList());
            outstockListDTO.setType(OutstockTypeEnum.WORK_ORDER_OUTSTOCK.getCode());
            List<PaasFormDataEntityExt> outstockList = outstockModel.findOutstockList(formDataDeleteBatchDTO.getDataIdList(), OutstockTypeEnum.WORK_ORDER_OUTSTOCK.getCode(), null, formDataDeleteBatchDTO.getCorpid(), null);
            if (!Objects.equals(outstockList.size(), BasicConstant.ZERO)) {
                throw new XbbException(WorkOrderErrorCodeEnum.API_ERROR_222069);
            }

            // 全部工单列表，快速删除处理
            List<Long> dataIds = formDataDeleteBatchDTO.getDataIdList();
            if (dataIds != null && dataIds.size() < 1) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100002);
            }
            WorkOrderEntity workOrderEntity = workOrderModel.getByKey(dataIds.get(0), corpid);
            formId = workOrderEntity.getFormId();
        }
        WorkOrderFormEntityExt workOrderFormEntityExt = workOrderFormModel.getByKey(formId, corpid);
        if(Objects.isNull(workOrderFormEntityExt)){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }

        return workOrderFormEntityExt;
    }



    @Override
    public FormDataDeleteBatchVO deleteBatchNoPermission(FormDataDeleteBatchDTO formDataDeleteBatchDTO, WorkOrderFormEntityExt formEntityExt) throws XbbException {

        List<WorkOrderEntity> list = deleteEsData(formDataDeleteBatchDTO, formDataDeleteBatchDTO.getDataIdList(), formDataDeleteBatchDTO.getCorpid());
        ErrorDataPojo errorDataPojo = notAllowData(formDataDeleteBatchDTO, list);

        List<Long> deleteIdIn = deleteData(formDataDeleteBatchDTO, errorDataPojo.getDeleteList(), list, formDataDeleteBatchDTO.getCorpid());
        log(formDataDeleteBatchDTO, list, errorDataPojo);
        FormDataDeleteBatchVO formDataDeleteBatchVO = new FormDataDeleteBatchVO();
        formDataDeleteBatchVO.setDeleteIds(deleteIdIn);
        formDataDeleteBatchVO.setErrorDataList(errorDataPojo.getErrorDataList());
        formDataDeleteBatchVO.setErrorTypeList(errorDataPojo.getErrorTypeList());
        formDataDeleteBatchVO.setErrorDataMemo(errorDataPojo.getErrorDataMemo());
        return formDataDeleteBatchVO;
    }



    @Override
    public List<WorkOrderEntity> deleteEsData(FormDataDeleteBatchDTO workOrderDeleteBatchDTO, List<Long> dataIdIn, String corpid) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, corpid);
        param.put("idIn", dataIdIn);
        List<WorkOrderEntity> workOrderEntityList = workOrderModel.findEntitys(param);
        if (Objects.isNull(workOrderEntityList)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        List<Long> physicalDelIds = new ArrayList<>();
        physicalDelIds.addAll(dataIdIn);
        List<Long> deleteIdIn = new ArrayList<>();
        //查询名称
        List<String> workOrderName= new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

        for (WorkOrderEntity entity : workOrderEntityList) {


            deleteIdIn.add(entity.getId());
            if (physicalDelIds.contains(entity.getId())) {
                physicalDelIds.remove(entity.getId());
            }
            //查询编号+名称
            String name = entity.workOrderName();
            workOrderName.add(name);
        }
        if (!physicalDelIds.isEmpty()) {
            if(BasicConstant.ONE.equals(workOrderDeleteBatchDTO.getSingleFlag())
                    && BasicConstant.ONE.equals(physicalDelIds.size())){
                paasEsModel.delete(physicalDelIds.get(0),corpid, IndexTypeEnum.IDX_SAAS_WORK_ORDER,null);
            }else {
                // 删除es中存在，数据库不存在的数据
                paasEsModel.deleteBatch(physicalDelIds, corpid, DelEnum.DELETE.getDel(), IndexTypeEnum.IDX_SAAS_WORK_ORDER);
            }
        }
        return workOrderEntityList;
    }

    @Override
    public ErrorDataPojo notAllowData(FormDataDeleteBatchDTO workOrderDeleteBatchDTO, List<WorkOrderEntity> dataIdIn) throws XbbException {
        List<Long> idIn = workOrderDeleteBatchDTO.getDataIdList();
        String corpid = workOrderDeleteBatchDTO.getCorpid();
        //工单下游单据校验，有出库单就不允许删除
        List<Long> hasDownstreamList = outstockModel.hasDownstreamList(corpid,idIn,OutstockTypeEnum.WORK_ORDER_OUTSTOCK.getCode());
        delErrorMsg(corpid,hasDownstreamList);
        ErrorDataPojo errorDataPojo = new ErrorDataPojo();
        errorDataPojo.setDeleteList(idIn);
        return errorDataPojo;
    }

    @Override
    public List<Long> deleteData(FormDataDeleteBatchDTO workOrderDeleteBatchDTO, List<Long> deleteIdIn, List<WorkOrderEntity> workOrderEntityList, String corpid) throws XbbException {
        if (!deleteIdIn.isEmpty()) {
            if(BasicConstant.ONE.equals(workOrderDeleteBatchDTO.getSingleFlag())
                    && BasicConstant.ONE.equals(deleteIdIn.size())){
                workOrderModel.deleteByKey(deleteIdIn.get(0),corpid);
            }else {
                workOrderModel.deleteBatch(deleteIdIn, corpid);
            }
            //工单产品删除
            workOrderProductModel.deleteByWorkOrderIdIn(deleteIdIn, corpid);
            //工单工作流删除,节点删除
            workOrderFlowNodeModel.deleteByWorkOrderIdIn(deleteIdIn, corpid);
            //工单团队删除
            workOrderFlowUserModel.batchDeleteByWorkOrderId(corpid, deleteIdIn, null);
        }
        // TODO: 2019/5/9  出库单老逻辑没删除,新的不知道要不要 ,产品凤娇说不删  @date 2019/5/9 11:26

        // TODO 删除相关审批记录

        UserVO loginUser = workOrderDeleteBatchDTO.getLoginUser();
        // 工单删除消息推送
        for (WorkOrderEntity entity : workOrderEntityList) {
            List<String> pushUserIds = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.WORKORDER_DEL_PUSH.getCode(), PushTypeEnum.WORKORDER_DEL_PUSH.getSubCode(), loginUser, entity);
            PushRefTypePojo.Options options = new PushRefTypePojo.Options(entity.getAppId(), entity.getMenuId(), entity.getFormId(), entity.getId(), SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.WORK_ORDER.getCode());
            if (Objects.nonNull(pushUserIds) && pushUserIds.size() > 0) {
                MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserIds, Collections.singletonList(entity.getId()), 0, null, I18nMessageUtil.getMessage(WorkOrderPushConstant.WORK_ORDER_DEL_TITLE), String.format(I18nMessageUtil.getMessage(WorkOrderPushConstant.PUSH_DEL), loginUser.getName(), entity.getSerialNo()), null, options);
                baseProducer.sendMessage(PushTypeEnum.WORKORDER_DEL_PUSH, messageRabbitMqDTO);
            }
        }
        return deleteIdIn;
    }

    @Override
    public void log(FormDataDeleteBatchDTO workOrderDeleteBatchDTO, List<WorkOrderEntity> workOrderEntityList, ErrorDataPojo errorDataPojo) throws XbbException {
        OperateTypeEnum operateTypeEnum = OperateTypeEnum.DELETE;
        if (Objects.equals(1, workOrderDeleteBatchDTO.getIsBusinessRule())) {
            operateTypeEnum = OperateTypeEnum.RULE_DELETE;
        }
        List<String> workOrderName = new ArrayList<>();
        List<Long> deleteIdIn = errorDataPojo.getDeleteList();
        for (WorkOrderEntity entity : workOrderEntityList) {
            //查询编号+名称
            String name = entity.workOrderName();
            workOrderName.add(name);
        }
        String corpid = workOrderDeleteBatchDTO.getCorpid();
        //生成删除日志(区分单个删除和批量删除)
        String userId = workOrderDeleteBatchDTO.getUserId();
        String userName = workOrderDeleteBatchDTO.getLoginUserName();
        String nameStr = StringUtils.join(workOrderName, "，");
        if(deleteIdIn.size() > 1){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DELETE_FORM_DETAIL), userName, XbbRefTypeEnum.WORK_ORDER.getName(), deleteIdIn.size());
            List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            InfoArrPojo infoArrPojo = new InfoArrPojo();
            infoArrPojo.setTitle(WorkOrderEnum.SHEET_NO.getAttrName());
            infoArrPojo.setContent(nameStr);
            infoArrPojoList.add(infoArrPojo);
            mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.WORK, operateTypeEnum,
                    "", "", memo, workOrderDeleteBatchDTO.getHttpHeader());
        } else if (Objects.equals(deleteIdIn.size(), 1)){
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), userName, XbbRefTypeEnum.WORK_ORDER.getName(), nameStr);
            mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.WORK, operateTypeEnum,
                    deleteIdIn.get(0).toString(), nameStr, memo, workOrderDeleteBatchDTO.getHttpHeader());
        }
    }

    @Override
    public void deleteAfter(List<Long> dataIdList, FormDataDeleteBatchDTO formDataDeleteBatchDTO, WorkOrderFormEntityExt form) throws XbbException {
        lowCodeExecuteService(dataIdList, SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.WORK_ORDER.getCode(), form.getId(), formDataDeleteBatchDTO.getCorpid());

        startWorkflow(formDataDeleteBatchDTO,  form.getBusinessRules(), dataIdList);

    }

    @Override
    public void rollback(List<Long> list, String corpid) {

    }

    /**
     * 批量删除工单，只要有工单拥有下游单据，就报错不允许删除
     * @param corpid
     * @param hasDownstreamList
     */
    private void delErrorMsg(String corpid, List<Long> hasDownstreamList) throws XbbException {
        if (!hasDownstreamList.isEmpty()){
            Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put(StringConstant.CORPID,corpid);
            map.put("idIn",hasDownstreamList);
            map.put("columns","serial_no");
            List<WorkOrderEntity> workOrderEntityList = workOrderModel.findEntitys(map);
            StringBuilder stringBuilder = new StringBuilder();
            workOrderEntityList.forEach(item -> stringBuilder.append(item.getSerialNo()).append(","));
            throw new XbbException(WorkOrderErrorCodeEnum.API_ERROR_222070, String.format(WorkOrderErrorCodeEnum.API_ERROR_222070.getMsg(),stringBuilder.toString()));
        }
    }
}
